#define MSLOG_C
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>    //struct itimerval, setitimer()
#include <time.h>
#include "mslog.h"

#define FLAG "MSLOG"

ms_bool flag_stdPrint		=ms_true;	//标记是否启用了标准打印
ms_bool flag_printLineFunc	=ms_true;	//标记是否启用行和函数打印
ms_bool flag_logFile		=ms_false;	//标记是否启用文件日志功能
ms_array strfilterTags[4096]={0};
const ms_string strLoglevel_simple[32]={"A","E","W","I","D","V","M"};

/*内部使用*/
static const ms_string strLoglevel[32]={"ASSERT","ERROR","WARING","INFO","DEBUG","VERBOSE","MORE","MAXLEVEL"};
static ENLOGLevel mslogLevel=mslog_level_more;
static ms_u32 mslogOpt=(mslog_level_more|mslog_enable_stdprint|mslog_enable_linefunc);
static pthread_mutex_t mutex_logfile;
static ms_array mslogfile_path[256]={0};
static ms_array mslogfile_name[512]={0};
static FILE * mslogfile_fp = ms_null;

#define mslog_default_dir	"/var/log/mslog"
#define mslog_default_filename "mslog.txt"
#define mslog_num_perkline 	16

#define mslog_bits_level(logopt) 	(logopt&0xF)
#define mslog_bits_stdprint(logopt)	(logopt&mslog_enable_stdprint)
#define mslog_bits_linefunc(logopt)	(logopt&mslog_enable_linefunc)
#define mslog_bits_filelog(logopt) 	(logopt&mslog_enable_filelog)
#define mslog_bits_timeus(logopt) 	(logopt&mslog_enable_timeus)

#define mslog_strcats(tbuf,obuf,fmt,arg...) memset(tbuf,0,strlen(tbuf)); \
	if(sizeof(tbuf)>8){ snprintf(tbuf,sizeof(tbuf),fmt,##arg); } \
	else{ sprintf(tbuf,fmt,##arg); } \
	strcat(obuf,tbuf); 

static ms_void mslog_innerapi_enStdprint(ms_bool ms_in enable)
{
	if(enable!=flag_stdPrint){
		ms_verbose("%s the function to print standard output",(ms_true==enable) ? "Enable" :"Disable");
	}
	flag_stdPrint=enable;
}
static ms_void mslog_innerapi_enLinefunc(ms_bool ms_in enable)
{
	if(enable!=flag_printLineFunc){
		ms_verbose("%s the function to print file lines and function names",(ms_true==enable) ? "Enable" :"Disable");
	}
	flag_printLineFunc=enable;
}
static ms_void mslog_innerapi_fileOpen(ms_u32 ms_in mslog_opt)
{
	if(!mslog_bits_filelog(mslog_opt )){
		return;
	}
	ms_array cmdline[512]={0};
	//创建日志目录
	snprintf(cmdline,sizeof(cmdline),"mkdir -p %s",mslogfile_path);
	system(cmdline);

	if(ms_false==flag_logFile){
		//对当前日志进行备份
		if(!(access(mslogfile_name,F_OK)<0)){
			ms_s08 strCurDTime[64]={0};
			snprintf(cmdline,sizeof(cmdline),"mv  %s    %s_%s.txt",mslogfile_name,
				mslogfile_name,mslog_api_curDTime("%04d%02d%02d_%02d%02d%02d",strCurDTime));
			system(cmdline);
		}
		//打开日志文件
		mslogfile_fp = fopen(mslogfile_name, "a+");
		flag_logFile=ms_true;
	}
}
static ms_void mslog_innerapi_fileClose(ms_void)
{
	if(ms_true==flag_logFile){
		flag_logFile=ms_false;
		fclose(mslogfile_fp);
	}
}
static ms_void mslog_innerapi_setLoglevel(ms_u08 ms_in loglevel)
{	
	if(loglevel<mslog_level_assert||loglevel>(mslog_level_max-1) ){
		ms_u32 cur_mslog_level=mslogLevel;
		//将级别设置为错误，避免级别不够导致无法错误提示
		mslogLevel=mslog_level_error;
		ms_error("Cur loglevel is %s(%d),and the set loglevel is %d , which is out of the range:[%d-%d]",
			strLoglevel[cur_mslog_level],cur_mslog_level,loglevel,mslog_level_assert,(mslog_level_max-1));
		//复原日志级别
		mslogLevel=cur_mslog_level;	
	}else if(mslog_api_getLoglevel()!=loglevel){
		ms_verbose("Set log level from %s to %s",strLoglevel[mslog_api_getLoglevel()],strLoglevel[loglevel]);
		mslogLevel=loglevel;
	}
}
static ms_string mslog_innerapi_runtimeUs(ms_string ms_out strRunTime)
{
	static ms_u64 log_baseTime=0;
	if(0==log_baseTime){
		log_baseTime=mslog_api_us();//记录起始时间
	}
	ms_u64 log_runTime=mslog_api_us()-log_baseTime;
	mslog_api_us2time(log_runTime,strRunTime,".%03d","%02d(s).%d.%d");
	return strRunTime;
}

/*------以下对外接口，但通过宏对外-------*/
ms_string mslog_innerapi_num2str( ms_string ms_out outstr, ms_s64 ms_in num)
{
	ms_pamcheckRet(ms_null, outstr, "outstr");
	snprintf(outstr, 32, "%"PRId64, num);
	return outstr;
}
ms_string mslog_innerapi_bitByte64( ms_string ms_out outstr, ms_u64 ms_in num64_h, ms_u64 ms_in num64_l ,ms_string punit)
{
	ms_pamcheckRet(ms_null, outstr, "outstr");
	//获取小数点后2位
	ms_u64 num_100=(num64_l*10)/1024;
	ms_u64 num_010=(((num64_l*10)%1024)*100)/1024;
	if(ms_null==punit){
		//6.35
		snprintf(outstr, 32, "%"PRId64".""%"PRId64"%"PRId64,num64_h,num_100,num_010);
	}else{
		//6.35 GB
		snprintf(outstr, 32, "%"PRId64".""%"PRId64"%"PRId64 " %s", num64_h,num_100,num_010,punit);
	}
	return outstr;
}
ms_string mslog_innerapi_bitByte32( ms_string ms_out outstr, ms_u32 ms_in num32_h, ms_u32 ms_in num32_l,ms_string punit)
{
	ms_pamcheckRet(ms_null, outstr, "outstr");
	ms_u32 num_100=(num32_l*10)/1024;
	ms_u32 num_010=(((num32_l*10)%1024)*100)/1024;
	if(ms_null==punit){
		//6.35
		snprintf(outstr, 32, "%u.%u%u       ", num32_h,num_100,num_010);
	}else{
		//6.35 GB
		snprintf(outstr, 32, "%u.%u%u %s", num32_h,num_100,num_010,punit);
	}
	return outstr;
}
ms_string mslog_innerapi_logTime(ms_void)
{	
	static ms_s08 strLogTime[64]={0};
	if(!mslog_bits_timeus(mslogOpt )){
		return mslog_api_curDTime("%04d-%02d-%02d %02d:%02d:%02d",strLogTime);
	}else{
		return mslog_innerapi_runtimeUs(strLogTime);
	}
}
ms_void mslog_innerapi_bufHex( ms_string ms_in des,ms_pu08 ms_in buf, ms_u32 ms_in len,ms_cstring ms_in func,ms_u32 ms_in line)
{
	ms_pamcheck( des, "des");
	ms_pamcheck( buf, "buf");
	
	ms_debug(">>>%s<<<---len:%d,mslog_num_perkline:%d,in func %s,line %d",des,len,mslog_num_perkline,func,line);
	
	ms_u32  lineindex = 0;
	for (lineindex=0; lineindex < len; lineindex+=mslog_num_perkline	){
		if ( (len-lineindex) <mslog_num_perkline	){
			unsigned char tempbuf[mslog_num_perkline]={0};
			memcpy(tempbuf, &buf[lineindex], (len-lineindex)	);
			ms_debug( "[%08x:%08x]%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ",
			lineindex,(lineindex+0x0f),
			tempbuf[0x00] ,tempbuf[0x01] ,tempbuf[0x02] ,tempbuf[0x03] ,tempbuf[0x04] ,tempbuf[0x05] ,tempbuf[0x06] ,tempbuf[0x07] ,
			tempbuf[0x08] ,tempbuf[0x09] ,tempbuf[0x0a] ,tempbuf[0x0b] ,tempbuf[0x0c] ,tempbuf[0x0d] ,tempbuf[0x0e] ,tempbuf[0x0f] );		
		}else{
			ms_debug( "[%08x:%08x]%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ",
			lineindex,(lineindex+0x0f),
			buf[lineindex+0x00] ,buf[lineindex+0x01] ,buf[lineindex+0x02] ,buf[lineindex+0x03] ,buf[lineindex+0x04] ,buf[lineindex+0x05] ,buf[lineindex+0x06] ,buf[lineindex+0x07] ,
			buf[lineindex+0x08] ,buf[lineindex+0x09] ,buf[lineindex+0x0a] ,buf[lineindex+0x0b] ,buf[lineindex+0x0c] ,buf[lineindex+0x0d] ,buf[lineindex+0x0e] ,buf[lineindex+0x0f] );
		}
	}
}
ms_void mslog_innerapi_bufHexAscii( ms_string ms_in des,ms_pu08 ms_in buf, ms_u32 ms_in len,ms_cstring ms_in func,ms_u32 ms_in line)
{
	ms_pamcheck( des, "des");
	ms_pamcheck( buf, "buf");
	
	ms_debug(">>>%s<<<---len:%d,mslog_num_perkline:%d,in func %s,line %d",des,len,mslog_num_perkline,func,line);
	
	ms_u32  lineindex = 0;
	for (lineindex=0; lineindex < len; lineindex+=mslog_num_perkline	){
		if ( (len-lineindex) <mslog_num_perkline	){
			unsigned char tempbuf[mslog_num_perkline]={0};
			memcpy(tempbuf, &buf[lineindex], (len-lineindex)	);
			ms_debug( "[%08x:%08x]%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x \t%c %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c",
			lineindex,(lineindex+0x0f),
			tempbuf[0x00] ,tempbuf[0x01] ,tempbuf[0x02] ,tempbuf[0x03] ,tempbuf[0x04] ,tempbuf[0x05] ,tempbuf[0x06] ,tempbuf[0x07] ,
			tempbuf[0x08] ,tempbuf[0x09] ,tempbuf[0x0a] ,tempbuf[0x0b] ,tempbuf[0x0c] ,tempbuf[0x0d] ,tempbuf[0x0e] ,tempbuf[0x0f] ,
			tempbuf[0x00] ,tempbuf[0x01] ,tempbuf[0x02] ,tempbuf[0x03] ,tempbuf[0x04] ,tempbuf[0x05] ,tempbuf[0x06] ,tempbuf[0x07] ,
			tempbuf[0x08] ,tempbuf[0x09] ,tempbuf[0x0a] ,tempbuf[0x0b] ,tempbuf[0x0c] ,tempbuf[0x0d] ,tempbuf[0x0e] ,tempbuf[0x0f] );		
		}else{
			ms_debug( "[%08x:%08x]%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x \t%c %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c",
			lineindex,(lineindex+0x0f),
			buf[lineindex+0x00] ,buf[lineindex+0x01] ,buf[lineindex+0x02] ,buf[lineindex+0x03] ,buf[lineindex+0x04] ,buf[lineindex+0x05] ,buf[lineindex+0x06] ,buf[lineindex+0x07] ,
			buf[lineindex+0x08] ,buf[lineindex+0x09] ,buf[lineindex+0x0a] ,buf[lineindex+0x0b] ,buf[lineindex+0x0c] ,buf[lineindex+0x0d] ,buf[lineindex+0x0e] ,buf[lineindex+0x0f],
			buf[lineindex+0x00] ,buf[lineindex+0x01] ,buf[lineindex+0x02] ,buf[lineindex+0x03] ,buf[lineindex+0x04] ,buf[lineindex+0x05] ,buf[lineindex+0x06] ,buf[lineindex+0x07] ,
			buf[lineindex+0x08] ,buf[lineindex+0x09] ,buf[lineindex+0x0a] ,buf[lineindex+0x0b] ,buf[lineindex+0x0c] ,buf[lineindex+0x0d] ,buf[lineindex+0x0e] ,buf[lineindex+0x0f] );
		}
	}
}
ms_void mslog_innerapi_bufHexErr( ms_string ms_in des,ms_pu08 ms_in buf, ms_u32 ms_in len,ms_cstring ms_in func,ms_u32 ms_in line)
{
	ms_pamcheck( des, "des");
	ms_pamcheck( buf, "buf");
	
	ms_error(">>>%s<<<---len:%d,mslog_num_perkline:%d,in func %s,line %d",des,len,mslog_num_perkline,func,line);
	
	ms_u32  lineindex = 0;
	for (lineindex=0; lineindex < len; lineindex+=mslog_num_perkline	){
		if ( (len-lineindex) <mslog_num_perkline	){
			unsigned char tempbuf[mslog_num_perkline]={0};
			memcpy(tempbuf, &buf[lineindex], (len-lineindex)	);
			ms_error( "[%08x:%08x]%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ",
			lineindex,(lineindex+0x0f),
			tempbuf[0x00] ,tempbuf[0x01] ,tempbuf[0x02] ,tempbuf[0x03] ,tempbuf[0x04] ,tempbuf[0x05] ,tempbuf[0x06] ,tempbuf[0x07] ,
			tempbuf[0x08] ,tempbuf[0x09] ,tempbuf[0x0a] ,tempbuf[0x0b] ,tempbuf[0x0c] ,tempbuf[0x0d] ,tempbuf[0x0e] ,tempbuf[0x0f] );		
		}else{
			ms_error( "[%08x:%08x]%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ",
			lineindex,(lineindex+0x0f),
			buf[lineindex+0x00] ,buf[lineindex+0x01] ,buf[lineindex+0x02] ,buf[lineindex+0x03] ,buf[lineindex+0x04] ,buf[lineindex+0x05] ,buf[lineindex+0x06] ,buf[lineindex+0x07] ,
			buf[lineindex+0x08] ,buf[lineindex+0x09] ,buf[lineindex+0x0a] ,buf[lineindex+0x0b] ,buf[lineindex+0x0c] ,buf[lineindex+0x0d] ,buf[lineindex+0x0e] ,buf[lineindex+0x0f] );
		}
	}
}
ms_void mslog_innerapi_bufAscii( ms_string ms_in des,ms_pu08 ms_in buf, ms_u32 ms_in len,ms_cstring ms_in func,ms_u32 ms_in line)
{
	ms_pamcheck( des, "des");
	ms_pamcheck( buf, "buf");
	
	ms_debug(">>>%s<<<---len:%d,mslog_num_perkline:%d,in func %s,line %d",des,len,mslog_num_perkline,func,line);
	
	ms_u32  lineindex = 0;
	for (lineindex=0; lineindex < len; lineindex+=mslog_num_perkline	){
		if ( (len-lineindex) <mslog_num_perkline	){
			unsigned char tempbuf[mslog_num_perkline]={0};
			memcpy(tempbuf, &buf[lineindex], (len-lineindex)	);
			ms_debug( "[%08x:%08x]%c %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c",
			lineindex,(lineindex+0x0f),
			tempbuf[0x00] ,tempbuf[0x01] ,tempbuf[0x02] ,tempbuf[0x03] ,tempbuf[0x04] ,tempbuf[0x05] ,tempbuf[0x06] ,tempbuf[0x07] ,
			tempbuf[0x08] ,tempbuf[0x09] ,tempbuf[0x0a] ,tempbuf[0x0b] ,tempbuf[0x0c] ,tempbuf[0x0d] ,tempbuf[0x0e] ,tempbuf[0x0f] );		
		}else{
			ms_debug( "[%08x:%08x]%c %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c",
			lineindex,(lineindex+0x0f),
			buf[lineindex+0x00] ,buf[lineindex+0x01] ,buf[lineindex+0x02] ,buf[lineindex+0x03] ,buf[lineindex+0x04] ,buf[lineindex+0x05] ,buf[lineindex+0x06] ,buf[lineindex+0x07] ,
			buf[lineindex+0x08] ,buf[lineindex+0x09] ,buf[lineindex+0x0a] ,buf[lineindex+0x0b] ,buf[lineindex+0x0c] ,buf[lineindex+0x0d] ,buf[lineindex+0x0e] ,buf[lineindex+0x0f] );
		}
	}
}
ms_s32 mslog_innerapi_write(ms_string ms_in filename,const char *format,...)
{
	va_list arg;
	va_start(arg,format);
	FILE *fp = fopen(filename, "a+");
	if(ms_null==fp){
		ms_byte cmdbuf[256]={0};
		snprintf(cmdbuf,sizeof(cmdbuf),"touch %s ",filename);
		system(cmdbuf);
		ms_errRet(-1,"Open (%s) failed",filename);
	}
	ms_s32 len = vfprintf(fp,format,arg);
	if (len<0){
		fclose(fp);
		ms_errRet(-1,"vfprintf (%s) failed",filename);
	}
	va_end(arg);
	fclose(fp);
	return len;

}
ms_void mslog_innerapi_file(const char *format,...)
{
	if(flag_logFile){ 
		static time_t mslogfile_Etimep=0;
		pthread_mutex_lock(&mutex_logfile);
		va_list arg;
		va_start(arg,format);
		if(ms_null!=mslogfile_fp){
			if(mslog_api_timerAsyncSec(&mslogfile_Etimep,60)){
				if(access(mslogfile_name,F_OK)<0){ //日志文件丢失，自动创建；
					fclose(mslogfile_fp);
					mslogfile_fp = fopen(mslogfile_name, "a+");
				}
			}
			ms_s32 len = vfprintf(mslogfile_fp,format,arg);
			if (len<0){
				ms_errGoto(msend,"vfprintf (%s) failed",mslogfile_name);
			}
			fflush(mslogfile_fp);
		}else{
			FILE *fp = fopen(mslogfile_name, "a+");
			if(ms_null==fp){
				ms_byte cmdbuf[256]={0};
				snprintf(cmdbuf,sizeof(cmdbuf),"touch %s ",mslogfile_name);
				system(cmdbuf);
				ms_errGoto(msend,"Open (%s) failed",mslogfile_name);
			}
			ms_s32 len = vfprintf(fp,format,arg);
			if (len<0){
				ms_errGoto(msend,"vfprintf (%s) failed",mslogfile_name);
			}
msend:	
			fclose(fp);
		}
		va_end(arg);
		pthread_mutex_unlock(&mutex_logfile); 
	}
}

//获取当前的日期和时间字符串，格式通过frm指定	
ms_string mslog_api_curDTime(ms_string ms_in frm,ms_string ms_out strCurDTime)
{
	struct tm p_tm;
	memset(&p_tm, 0, sizeof(struct tm));
	time_t timep=time(ms_null);
#if defined(OS_ANDROID)||defined(OS_LINUX_SOC)		
	localtime_r((time_t  *)&timep,&p_tm);
#else
	memcpy(&p_tm,localtime((time_t *)&timep),sizeof(struct tm));
#endif
	memset(strCurDTime,0,sizeof(strCurDTime));
	sprintf((char*)strCurDTime, frm,(p_tm.tm_year+1900),(p_tm.tm_mon+1),(p_tm.tm_mday),(p_tm.tm_hour),(p_tm.tm_min),(p_tm.tm_sec));
	return strCurDTime;
}
//获取当前的时间戳，单位微妙	
ms_u64 mslog_api_us(ms_void)
{
	struct timeval tv;
	memset(&tv, 0, sizeof(struct timeval));
	gettimeofday(&tv, ms_null);
	return (uint64_t)tv.tv_sec *(1000*1000)+ tv.tv_usec;
}
//异步计时，单位秒
ms_bool mslog_api_timerAsyncSec(time_t * ms_in Etimep,ms_u32 ms_in sec)	//s
{
	time_t cur_timep=time(ms_null);
	if(cur_timep<(*Etimep)){
	//系统时间被更改到过去，立马同步
		(*Etimep)=cur_timep;
		return ms_true;
	}else{
		if(cur_timep>((*Etimep)+sec)){
			(*Etimep)=cur_timep;
			return ms_true;
		}else{
			return ms_false;
		}
	}
} 
ms_string mslog_api_sec2Time(ms_u32 ms_in timesec,ms_string outbuf)
{
	memset(outbuf, 0, sizeof(outbuf));
	if(ms_f32==timesec){
		strcat(outbuf, "unvalid");
	}else{
		ms_u32 oneday	=60*60*24;
		ms_u32 onehour	=60*60;
		ms_u32 oneminute	=60;
		ms_u32 onesecond	=1;
		ms_u32 days   =(timesec/oneday);
		ms_u32 hours =(timesec%oneday)/onehour;
		ms_u32 minutes=((timesec%oneday)%onehour)/oneminute;
		ms_u32 secend=(((timesec%oneday)%onehour)%oneminute)/onesecond;
		ms_u08 tbuf[128]={0};
		if(days>0){
			memset(tbuf,0,sizeof(tbuf)); 
			sprintf(tbuf, "%d_", days);
			strcat(outbuf,tbuf);
		}
		memset(tbuf,0,sizeof(tbuf)); 
		sprintf(tbuf, "%d:%d:%d", hours,minutes,secend);
		strcat(outbuf,tbuf);
	}
	return outbuf;
}
ms_string mslog_api_us2time(ms_s64 ms_in timeus,ms_string outbuf,ms_string frm1,ms_string frm2)
{
	memset(outbuf, 0, sizeof(outbuf));
	if(-1==timeus){
		strcat(outbuf, "unvalid");
	}else{
		ms_u32 second   =(timeus/(1000*1000));
		ms_u32 msecond =(timeus%(1000*1000))/1000;
		ms_u32 usecond=((timeus%(1000*1000))%1000);
		ms_u08 tbuf[128]={0};
		if(second>60){
			mslog_api_sec2Time(second,outbuf);
			if(0!=msecond){
				memset(tbuf,0,sizeof(tbuf)); 
				sprintf(tbuf, frm1,msecond);
				strcat(outbuf,tbuf);
			}
			if(0!=usecond){
				memset(tbuf,0,sizeof(tbuf)); 
				sprintf(tbuf, frm1,usecond);
				strcat(outbuf,tbuf);	
			}
		}else{
			memset(tbuf,0,sizeof(tbuf)); 
			sprintf(tbuf, frm2, second,msecond,usecond);
			strcat(outbuf,tbuf);	
		}
	}
	return outbuf;
}

/*查找字符串strtarget在字符串strsrc中出现的次数
	flag_findret:查找到就立马返回，否则会一直查找，并返回出现的次数；
	flag_case_insensitive：忽略字母大小写；
*/
ms_s32 mslog_api_strCasestrNum(ms_cstring ms_in strsrc, ms_cstring ms_in strtarget,ms_bool flag_findret,ms_bool flag_Ignorelettercase)
{
	ms_s32 num_find=0;
	ms_s32 len_strtarget= strlen(strtarget);
	ms_s32 len_strsrc= strlen(strsrc);
	ms_s32 tries= strlen(strsrc) + 1 - len_strtarget; 
	ms_s32 index=0;
	if((0==len_strtarget)||(0==strsrc)){
		return 0;
	}
	while (tries > 0){
		for(index=0;index<len_strtarget;index++){
			char char_strsrc=strsrc[index] ;
			char char_strtarget=strtarget[index] ;
			//如果是小写字母，则全部装换为大写字母
			if(ms_true==flag_Ignorelettercase){
				if( ('a'-1)<char_strsrc&& char_strsrc<('z'-1) ){
					char_strsrc-=32;
				}
				if( ('a'-1)<char_strtarget&& char_strtarget<('z'-1) ){
					char_strtarget-=32;
				}	
			}
			//ms_debug("%c,%c",char_strsrc,char_strtarget);
			if(char_strsrc!=char_strtarget){
				//ms_debug("1----break");
				break;
			}
		}
		if(index==len_strtarget){
			num_find+=1;
			if(ms_true==flag_findret){
				break;
			}
		}	
		strsrc++;
		tries--;
	}
	return  num_find;
}
ms_void mslog_api_init(ms_u32 ms_in logopt,ms_string ms_in dir,ms_string ms_in logfile,ms_string ms_in filter_tags)
{
//设置日志过滤TAG	
	memset(strfilterTags,0,sizeof(strfilterTags));
	if(ms_null!=filter_tags){
		strcpy(strfilterTags,filter_tags);
	}
//设置日志级别
	mslog_innerapi_setLoglevel((ms_u08)mslog_bits_level(logopt) );
//设置标准输出开关
	if(mslog_bits_stdprint(logopt)){
		mslog_innerapi_enStdprint(ms_true);
	}else{
		mslog_innerapi_enStdprint(ms_false);
	}	
//设置输出打印所在文件行数和函数名
	if(mslog_bits_linefunc(logopt )){
		mslog_innerapi_enLinefunc(ms_true);
	}else{
		mslog_innerapi_enLinefunc(ms_false);
	}	
//设置输出日志文件
	if(mslog_bits_filelog(logopt )){
		//如果没有设置日志目录或日志文件，则使用默认值
		if(ms_null==dir){	
			ms_waring("The log directory is not set, using the default %s.", mslog_default_dir);
			dir=mslog_default_dir;
		}
		if(ms_null==logfile){	
			ms_waring("The log file name is not set, using the default	%s.", mslog_default_filename);
			logfile=mslog_default_filename;
		}
		//避免多次重复打开日志文件,也就是在调用释放资源接口前，是不允许修改日志文件的
		if(ms_false==flag_logFile){
			memset(mslogfile_path, 0, sizeof(mslogfile_path));
			memset(mslogfile_name, 0, sizeof(mslogfile_name));
			
			strcpy(mslogfile_path,dir);
			sprintf(mslogfile_name,"%s/%s",mslogfile_path,logfile);
			
			ms_debug("logfile:%s",mslogfile_name);

			int ret = pthread_mutex_init(&mutex_logfile, ms_null);
			if (ret != 0) {
				ms_error( "pthread_mutex_init failed : %s", strerror(ret));
			}
			ms_verbose("Open the function of printing log to file");
			mslog_innerapi_fileOpen(logopt);
		}else{
			ms_waring("Change logfile to %s/%s failed!!!Please call mslog_api_deinit fisrt",mslogfile_path,logfile);
		}
	}else{
		if(ms_true==flag_logFile){
			mslog_innerapi_fileClose();
			ms_debug("Close the function of printing log to file");
			pthread_mutex_destroy(&mutex_logfile);
		}
	}
//设置输出时间格式
	if(mslog_bits_timeus(logopt )){
		ms_verbose("Open the function of printing us time");
	}
	mslogOpt=logopt;
}
ms_u32 mslog_api_getOpt(ms_void)
{
	return mslogOpt;
}
ms_void mslog_api_getOptstring(ms_string ms_in outstr)
{
	sprintf(outstr, "%s|logfile:%s|%s|%s|%s|%s", strLoglevel[mslog_api_getLoglevel()],mslogfile_name,
		(mslog_bits_stdprint(mslogOpt)) ? "enable_stdprint" : "disable_stdprint",
		(mslog_bits_linefunc(mslogOpt)) ? "enable_linefunc" : "disable_linefunc",
		(mslog_bits_filelog(mslogOpt)) ? "enable_filelog" : "disable_filelog",
		(mslog_bits_timeus(mslogOpt)) ? "enable_timeus" : "disable_timeus"
	);
}
ms_u32 mslog_api_getLoglevel(ms_void)
{
	return mslogLevel;
}
ms_string mslog_api_getLogfile(ms_void)
{
	return mslogfile_name;
}
ms_void mslog_api_deinit(ms_void)
{
	ms_u32 logopt=mslogOpt;
	if(mslog_bits_stdprint(logopt )){
		mslog_innerapi_enStdprint(ms_false);
		ms_debug("Close the function of printing stdin and stdout");
	}	
	if(mslog_bits_linefunc(logopt )){
		mslog_innerapi_enLinefunc(ms_false);
		ms_debug("Close the function of printing line and funcname");
	}	
	if(mslog_bits_filelog(logopt )){
		//避免多次重复关闭日志文件
		if(ms_true==flag_logFile){
			mslog_innerapi_fileClose();
			ms_debug("Close the function of printing log to file");
			pthread_mutex_destroy(&mutex_logfile);
		}
	}	
}
ms_void mslog_api_new(ms_void)
{
	mslog_innerapi_fileClose();
	mslog_innerapi_fileOpen(mslogOpt);
}
ms_void mslog_api_color(ms_void)
{
#if defined(OS_LINUX_SOC)
	PRINT("%s mscolor_nor(mscolor_black)" mscolor_reset LINE_END, mscolor_nor(mscolor_black));
	PRINT("%s mscolor_bold(mscolor_black)" mscolor_reset LINE_END, mscolor_bold(mscolor_black));
	PRINT("%s mscolor_nor(mscolor_red)" mscolor_reset LINE_END, mscolor_nor(mscolor_red));
	PRINT("%s mscolor_bold(mscolor_red)" mscolor_reset LINE_END, mscolor_bold(mscolor_red));
	PRINT("%s mscolor_nor(mscolor_green)" mscolor_reset LINE_END, mscolor_nor(mscolor_green));
	PRINT("%s mscolor_bold(mscolor_green)" mscolor_reset LINE_END, mscolor_bold(mscolor_green));
	PRINT("%s mscolor_nor(mscolor_brown)" mscolor_reset LINE_END, mscolor_nor(mscolor_brown));
	PRINT("%s mscolor_bold(mscolor_brown)" mscolor_reset LINE_END, mscolor_bold(mscolor_brown));
	PRINT("%s mscolor_nor(mscolor_blue)" mscolor_reset LINE_END, mscolor_nor(mscolor_blue));
	PRINT("%s mscolor_bold(mscolor_blue)" mscolor_reset LINE_END, mscolor_bold(mscolor_blue));
	PRINT("%s mscolor_nor(mscolor_purple)" mscolor_reset LINE_END, mscolor_nor(mscolor_purple));
	PRINT("%s mscolor_bold(mscolor_purple)" mscolor_reset LINE_END, mscolor_bold(mscolor_purple));
	PRINT("%s mscolor_nor(mscolor_cyan)" mscolor_reset LINE_END, mscolor_nor(mscolor_cyan));
	PRINT("%s mscolor_bold(mscolor_cyan)" mscolor_reset LINE_END, mscolor_bold(mscolor_cyan));
	PRINT("%s mscolor_nor(mscolor_gray)" mscolor_reset LINE_END, mscolor_nor(mscolor_gray));
	PRINT("%s mscolor_bold(mscolor_gray)" mscolor_reset LINE_END, mscolor_bold(mscolor_gray));
#else
	PRINT("unsupport" LINE_END);
#endif
}

ms_void mslog_api_info(ms_string ms_out pbuf)
{
#ifdef OS_LINUX_SOC  
	strcat(pbuf, "linux_soc");
#else
	strcat(pbuf, "unlinux_soc");
#endif
	strcat(pbuf, "|all-func");
}
ms_string mslog_api_version(ms_void)
{
	return "02.01.10";
}
#undef MSLOG_C
